/*
 * @Description: 精度计算
 * @Author: DHL
 * @Date: 2022-04-13 13:42:59
 * @LastEditors: DHL
 * @LastEditTime: 2022-09-18 21:40:57
 */


import BigNumber from 'bignumber.js'
import { isEmpty, isNumber, isString } from './isUtils'
import { stringUtils } from './stringUtils'
import { log } from './log'


/**
 * 精度计算
 */
export default class BigNum {
  private value: BigNumber

  constructor(val: number | string | null | undefined) {
    this.value = new BigNumber(this.getVal(val))
  }

  /**
   * 获取有效数字
   * @param val
   * @returns
   */
  private getVal(val: string | number | null | undefined): number {
    if (isEmpty(val)) {
      return 0
    }

    if (isNumber(val)) {
      return val
    }

    if (isString(val)) {
      return new BigNumber(stringUtils.trim(val, 1)).toNumber()
    }

    throw new Error(stringUtils.format('【{0}】不是有效数字', val))
  }

  /**
   * 解析结果
   * 获取数值
   * @returns
   */
  parse() {
    return this.value.toNumber()
  }

  /**
   * 加法运算
   * @param val 加数
   * @returns
   */
  add(val: string | number | null | undefined) {
    this.value = this.value.plus(this.getVal(val))
    return this
  }

  /**
   * 减法运算
   * @param val 减数
   * @returns
   */
  subtract(val: string | number | null | undefined) {
    this.value = this.value.minus(this.getVal(val))
    return this
  }

  /**
   * 乘法运算
   * @param val 乘数
   * @returns
   */
  multiply(val: string | number | null | undefined) {
    this.value = this.value.multipliedBy(this.getVal(val))
    return this
  }

  /**
   * 除法运算
   * @param val 除数
   * @returns
   */
  divide(val: string | number | null | undefined) {
    const v1 = this.getVal(val)
    if (v1 === 0) {
      log.warn('除数不能为零')
      return this
    }

    this.value = this.value.dividedBy(v1)
    return this
  }

  /**
   * 保留小数位
   * @param len
   * @returns
   */
  toFixed(len = 2) {
    this.value = this.value.decimalPlaces(len)
    return this
  }
}
